(ns acst.models.db
  (:require [clojure.java.jdbc :as sql]
            [acst.utils.handle-exp :as ex]
            [clojure.java.jdbc :as jdbc]
            [clojure.data.json :as json])
  (:import (org.postgresql.util PGobject)))

(defn value-to-json-pgobject [value]
  (doto (PGobject.)
    (.setType "jsonb")
    (.setValue (json/write-str value))))

(extend-protocol jdbc/ISQLValue
  clojure.lang.IPersistentMap
  (sql-value [value] (value-to-json-pgobject value))

  clojure.lang.IPersistentVector
  (sql-value [value] (value-to-json-pgobject value)))

(extend-protocol jdbc/IResultSetReadColumn
  PGobject
  (result-set-read-column [pgobj metadata idx]
    (let [type  (.getType pgobj)
          value (.getValue pgobj)]
      (case type
        "jsonb" (json/read-str value :key-fn keyword)
        :else value))))

(def db
  {:subprotocol "postgresql"
   :subname "//localhost:5432/acst"
   :user "acst"
   :password "acst"
   })

;(def db
;  {:subprotocol "postgresql"
;   :subname "//ec2-54-228-219-2.eu-west-1.compute.amazonaws.com:5432/d4rbks5908a2rh"
;   :user "xlfyjvfcikpsjo"
;   :password "-ZsB0aeWdRfuRjUDlhrjIt8D5u"
;   })



(defmacro do-commands [f & body]
  `(sql/db-do-commands
     ~db
     (~f ~@body)))

(defmacro query [default body]
  `(ex/handle-sqlex
     (let [result# (sql/query ~db ~body)]
           (cond
             (= '() result#)  ~default
             :else result#))))

(defmacro query-1 [body]
  `(ex/handle-sqlex
     (sql/query ~db ~body)))

(defmacro insert! [table row]
  `(ex/handle-sqlex
    (sql/insert! ~db
                 ~table
                 ~row)))

(defmacro update! [table set-map where-clause]
  `(ex/handle-sqlex
     (sql/update! ~db
                  ~table
                  ~set-map
                  ~where-clause)))

(defmacro delete! [table where-clause]
  `(ex/handle-sqlex
     (sql/delete! ~db
                  ~table
                  ~where-clause
                  )))

;(defmacro defquery)



